package org.simple.jdbc.statement.proxy;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author jinchengzhen
 */
public abstract class BaseStatementProxyImpl implements StatementProxy {
    protected DataSource dataSource;
    protected PreparedStatement preparedStatement;

    public BaseStatementProxyImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Connection getConnection() {
        try {
            Connection connection = dataSource.getConnection();
            connection.setAutoCommit(false);
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void setValue(int i, String typeName, Object o) {
        try {
            switch (typeName) {
                case "String":
                    preparedStatement.setString(i, (String) o);
                    break;
                case "Integer":
                    preparedStatement.setInt(i, (Integer) o);
                    break;
                case "Boolean":
                    preparedStatement.setBoolean(i, (Boolean) o);
                    break;
                case "Double":
                    preparedStatement.setDouble(i, (Double) o);
                    break;
                case "Float":
                    preparedStatement.setFloat(i, (Float) o);
                    break;
                case "Array":
                    preparedStatement.setString(i, Arrays.toString((Object[]) o));
                    break;
                case "List":
                    preparedStatement.setString(i, Arrays.toString(((List) o).toArray()));
                    break;
                case "Date":
                    preparedStatement.setDate(i, (Date) o);
                    break;
                default:
                    preparedStatement.setObject(i, o);
                    break;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    protected boolean executeBatch(PreparedStatement preparedStatement) throws SQLException {
        int[] nums = preparedStatement.executeBatch();
        if (nums.length == 1) {
            return nums[0] > 0;
        } else {
            List<String> resultFailed = new ArrayList<>();
            int ii = 1;
            for (int n : nums) {
                if (n <= 0) {
                    resultFailed.add(Integer.toString(ii));
                }
                ii++;
            }
            if (!resultFailed.isEmpty()) {
                if (Boolean.getBoolean("debug")) {
                    for (String n : resultFailed) {
                        System.out.println("Execute sql error at line : " + n);
                    }
                }
                throw new SQLException(String.join(System.lineSeparator(), resultFailed));
            }
        }
        return true;
    }
}
